package top.metaspace.io.mynio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

/**
 * @author panjun
 * @date 2018/6/28.
 */
public class NioServer {

	public static void main(String[] args) throws IOException {
		NioServer server = new NioServer();
		server.init();

	}


	public void init() throws IOException {
		Selector selector = Selector.open();
		ServerSocketChannel ssc = ServerSocketChannel.open();
		ssc.configureBlocking(false);
		ssc.socket().bind(new InetSocketAddress(9000),1024);
		ssc.register(selector,SelectionKey.OP_ACCEPT);

		while (true){
			selector.select(1000);
			Set<SelectionKey> keys = selector.selectedKeys();
			Iterator<SelectionKey> it = keys.iterator();
			while (it.hasNext()){
				SelectionKey key = it.next();
				it.remove();
				if(key.isAcceptable()){
					ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
					SocketChannel sc = serverSocketChannel.accept();
					sc.configureBlocking(false);
					sc.register(selector,SelectionKey.OP_READ);
				}else if(key.isReadable()){
					SocketChannel channel = (SocketChannel) key.channel();
					ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
					String content = "";
					try {
						int readBytes = channel.read(byteBuffer);
						if (readBytes > 0) {
							byteBuffer.flip(); //为write()准备
							byte[] bytes = new byte[byteBuffer.remaining()];
							byteBuffer.get(bytes);
							System.out.println(bytes.length);
							content+=new String(bytes);
							System.out.println(content);
							//回应客户端
						}
						// 写完就把状态关注去掉，否则会一直触发写事件(改变自身关注事件)
						key.interestOps(SelectionKey.OP_READ);
					} catch (IOException i) {
						//如果捕获到该SelectionKey对应的Channel时出现了异常,即表明该Channel对于的Client出现了问题
						//所以从Selector中取消该SelectionKey的注册
						key.cancel();
						if (key.channel() != null) {
							key.channel().close();
						}
					}

				}
			}
		}


	}




}
